package com.baymax.lib.key

import android.util.Log
import android.view.KeyEvent
import com.baymax.test.scene.internal.key.KeyCodeCombinationProcessor

/**
 * 满足按键条件后的一次作用域
 */

class KeySession private constructor(
    private val config: KeyProcessorConfig,
    val onStart: (KeySession) -> Unit,
    val onStop: (KeySession) -> Unit,
) {

    var lastRecordEvent: KeyEvent = EMPTY

    private val current = object : KeyCodeCombinationProcessor.Reference(EMPTY) {
        override fun onDisposed(keyEvent: KeyEvent) {
            this@KeySession.lastRecordEvent = keyEvent
            onStop(this@KeySession)
            this@KeySession.reset()
        }
    }

    val isDisposed: Boolean get() = current.isDisposed
    private val nextTimeout get() = current.get().downTime + config.inputDuration

    private val keyArray: MutableList<KeyEvent> = mutableListOf()

    val currentEvent :KeyEvent get() = current.get()

    private fun push(keyEvent: KeyEvent): Boolean {
        val n = nextTimeout
        return if (n >= keyEvent.downTime) {
            current.set(keyEvent)
            keyArray.add(keyEvent)
            true
        } else {
            Log.w("KeySession", String.format("time out %s", n, keyEvent))
            cancel(keyEvent)
            false
        }
    }


    fun start(keyEvent: KeyEvent) {
        if (current.isDisposed) {
            current.set(keyEvent)
            push(keyEvent)
            onStart(this)
        }
    }

    fun continueKeyEvent(keyEvent: KeyEvent): Boolean {
        return push(keyEvent)
    }


    fun snapShot(): List<KeyEvent> = keyArray.toList()

    private fun reset() {
        keyArray.clear()
    }

    fun complete(keyEvent: KeyEvent): Boolean {
        //完成
        if (!current.isDisposed) {
            current.set(keyEvent)
            current.dispose()
            return true
        }
        return false
    }

    fun cancel(keyEvent: KeyEvent): Boolean {
        if (!current.isDisposed) {
            current.set(keyEvent)
            current.dispose()
            return true
        }
        return false
    }


    fun outThrottle(keyEvent: KeyEvent): Boolean {
        val last = lastRecordEvent
        if (last != EMPTY) {
            return keyEvent.downTime - last.downTime >= config.intervalDuration
        }
        return true
    }

    override fun toString(): String {
        return "KeySession(lastRecordEvent=$lastRecordEvent, keyArray=$keyArray, currentEvent=$currentEvent)"
    }


    companion object {
        internal val EMPTY = KeyEvent(
            Int.MAX_VALUE.toLong(), Int.MAX_VALUE.toLong(),
            KeyEvent.ACTION_DOWN, -1, -1, 0
        )


        fun newSession(
            config: KeyProcessorConfig,
            onStart: (KeySession) -> Unit,
            onStop: (KeySession) -> Unit
        ): KeySession {
            return KeySession(config, onStart, onStop)
        }
    }



}


